#include "VFunctions.h"
#include <QChar>
#include <QString>
#include <qsettings.h>
#include <qfile.h>
#include <qdir.h>
#include <qsettings.h>
#include <qstringlist.h>
#include <qdebug.h>
#include <QTextCodec>
#include <QCoreApplication>
#include <QProcess>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonParseError>
#include <QStringList>
#include <QRegularExpression>
#include <QMessageBox>

#include <string>
#include "VGlobal.h"
#include "VTranslate.h"

namespace VFunctions
{
    QString get_ini_value(const QString full_path, const QString group, const QString item, QString default_value)
	{
		QSettings settings(full_path, QSettings::IniFormat);
		settings.setIniCodec("utf-8");
        return settings.value(group + "/" + item, default_value).toString();
	}

    bool set_ini_value(const QString full_path, const QString group, const QString item, const QString value)
	{
		QSettings settings(full_path, QSettings::IniFormat);
		settings.setIniCodec("utf-8");
		settings.setValue(group + "/" + item, QVariant(value));
		return true;
	}

    bool creat_dir(const QString dir_path, const QString folder_name)
	{
		QDir dir;
		dir.cd(dir_path);
		if (dir.exists())
		{
			dir.mkdir(folder_name);
			return true;
		}
		return false;
	}

    bool creat_file(const QString full_path)
	{
		QFile file(full_path);
		if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
		{
			return false;
		}
		file.close();
		return true;
	}

	bool _pint_yin_map_init = false;
	QMap<int, QString> _pint_yin_map;
	bool matching_string(const QString source, const QString input)
	{
		// 判断拼音是否初始化
		if (_pint_yin_map_init == false)
		{
			// :/MainWindow/Resources/defalut.qss
            QSettings file_setting(":/new/prefix1/Resource/pingyin.ini", QSettings::IniFormat);
			file_setting.beginGroup("default");
			QStringList str_list = file_setting.childKeys();
            foreach (QString key, str_list)
			{
				_pint_yin_map.insert(key.toInt(), file_setting.value(key).toString());
			}
			_pint_yin_map_init = true;
		}

		// 开始匹配
		int source_length = source.length();
		int input_length = input.length();

		if (source_length == 0 || input_length == 0)
		{
			return false;
		}

		int source_pos = 0;
		int input_pos = 0;
		
		for (size_t i = 0; i < input_length; i++)
		{
			int ascall = input.at(input_pos).unicode();
			if (ascall <= 127)
			{
				if (source.at(source_pos).unicode() <= 127)
				{
                    if (input.at(input_pos) != source.at(source_pos)
                            && input.at(input_pos) != source.at(source_pos).toLower())
					{
						return false;
					}
					
					input_pos++;
					source_pos++;
				}
				else
				{
					QString pingyin_str = _pint_yin_map.value(source.at(source_pos).unicode());
					int pingyin_length = pingyin_str.length();
					if (pingyin_length == 0)
					{
						return false;
					}

					if (input.at(input_pos) != pingyin_str.at(0))
					{
						return false;
					}

					int j;
					for (j = 0; j < pingyin_length; j++)
					{
						if (input_pos + j >= input_length || input.at(input_pos + j) != pingyin_str.at(j))
						{
							j--;
							break;
						}
					}

					if (j == pingyin_length)
					{
						input_pos += pingyin_length;
						source_pos++;
					}
					else
					{
						if (input_pos + j + 1 >= input_length)
						{
							break;
						}
						else
						{
							input_pos++;
							source_pos++;
						}
					}
				}
			}
			else
			{
				if (input.at(input_pos) != source.at(source_pos))
				{
					return false;
				}

				input_pos++;
				source_pos++;
				
				if (input_pos >= input_length)
				{
					break;
				}

				if (source_pos >= source_length)
				{
					return false;
				}
			}

			if (input_pos >= input_length)
			{
				break;
			}

			if (source_pos >= source_length)
			{
				return false;
			}
		}


		return true;
	}

	void clearFiles(const QString &folderFullPath)
	{
		QDir dir(folderFullPath);
		dir.setFilter(QDir::Files);
		int fileCount = dir.count();
		for (int i = 0; i < fileCount; i++)
            dir.remove(dir[i]);
    }

    QString read_file_text(QString path)
    {
        QString result;
        QFile file(path);
        if(file.open(QFile::ReadOnly) == false)
        {
            qDebug() <<   "QString read_file_text(QString path) : open file error!";
            return result;
        }

        QTextStream in(&file);
        in.setCodec("utf-8");
        result = in.readAll();
        file.close();

        return result;
    }

    bool save_file(QString path, QString text)
    {
        QFile file(path);
        if (!file.open(QFile::WriteOnly))
        {
            // error
            qDebug() << "oepn error";
        }

        QTextStream out(&file);
        out.setCodec("utf-8");
        out << text;
        file.close();
    }

    QString get_c_keyword_zn_to_en(QString word)
    {
        if(VGlobal::keyword_cn_en.contains(word))
        {
            return VGlobal::keyword_cn_en.value(word);
        }
        return "";
    }

    bool is_chinese(QString word)
    {
        foreach (QChar c, word)
        {
            ushort uni = c.unicode();
            if (uni >= 0x4E00 && uni <= 0x9FA5)
            {
                return true;
            }
        }
        return false;
    }

    QString GBK2UTF8(const QString &inStr)
    {
        QTextCodec *gbk = QTextCodec::codecForName("GB18030");
        QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

        QString g2u = gbk->toUnicode(gbk->fromUnicode(inStr));              // gbk  convert utf8
        return g2u;
    }

    QString UTF82GBK(const QString &inStr)
    {
        QTextCodec *gbk = QTextCodec::codecForName("GB18030");
        QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

        QString utf2gbk = gbk->toUnicode(inStr.toLocal8Bit());
        return utf2gbk;
    }

    std::string gbk2utf8(const QString &inStr)
    {
        return GBK2UTF8(inStr).toStdString();
    }

    QString utf82gbk(const std::string &inStr)
    {
        QString str = QString::fromStdString(inStr);

        return UTF82GBK(str);
    }

    bool save_file_to_gbk(QString path, QString text)
    {
        QFile file(path);
        if (!file.open(QFile::WriteOnly))
        {
            qDebug() << "open error";
        }

        QTextStream out(&file);
        out.seek(0);
        out.setCodec("gbk");
        out << VFunctions::UTF82GBK(text);
        out.seek(0);
        file.close();
    }

    QString read_gbk_file_text(QString path)
    {
        QString result;
        QFile file(path);
        if(file.open(QFile::ReadOnly) == false)
        {
            qDebug() <<   "QString read_file_text(QString path) : open file error!";
            return result;
        }

        QTextStream in(&file);
        in.setCodec("gbk");
        result = GBK2UTF8(in.readAll());
        file.close();

        return result;
    }

    void init_path()
    {
        VGlobal::current_dir = QCoreApplication::applicationDirPath();
        VGlobal::sdcc_path = VGlobal::current_dir + "/sdcc/bin/sdcc.exe";
        VGlobal::packihx_path = VGlobal::current_dir + "/sdcc/bin/packihx.exe";
        VGlobal::lua_path = VGlobal::current_dir + "/lua/lua.exe";
        VGlobal::lua_module_dir_path = VGlobal::current_dir + "/lua/lua";
        VGlobal::compress_path = VGlobal::current_dir + "/7z/7za.exe";
        VGlobal::intent_path = VGlobal::current_dir + "/indent/indent.exe";
        VGlobal::temp_dir = VGlobal::current_dir + "/temp";
        VGlobal::log_path = VGlobal::current_dir + "/log/log.txt";
        VGlobal::log_dir = VGlobal::current_dir + "/log";
        VGlobal::config_dir = VGlobal::current_dir + "/config";
        VGlobal::config_path = VGlobal::current_dir + "/config/config.ini";
        VGlobal::skins_dir = VGlobal::current_dir + "/skins";
        VGlobal::ctags_path = VGlobal::current_dir + "/ctags/ctags.exe";
        VGlobal::historical_record_path = VGlobal::current_dir + "/config/historical.txt";
    }

    void load_setting()
    {
        QJsonObject parent = VFunctions::get_file_jsonDocument(VGlobal::config_dir + "/setting.json").object();
        QJsonObject app = parent.value("app").toObject();
        VGlobal::setting.app_font_name = app.value("font").toString();
        VGlobal::setting.skin_name = app.value("skin").toString();

        QJsonObject code_edit = parent.value("code_edit").toObject();
        VGlobal::setting.textedit_font_name = code_edit.value("font").toString();
        VGlobal::setting.textedit_font_size = code_edit.value("font_size").toInt();
        VGlobal::setting.symbol = code_edit.value("symbol") == "true";
        VGlobal::setting.tab_width = code_edit.value("tab_width").toInt();

        QJsonObject code_format = parent.value("code_format").toObject();
        VGlobal::setting.code_format = code_format.value("summary").toString().split(";");

        QJsonObject intelligence = parent.value("intelligence").toObject();
        VGlobal::setting.intelligence_delay = intelligence.value("delay").toInt();

        QJsonObject toolbar = parent.value("toolbar").toObject();
        VGlobal::setting.tool_bar_build = toolbar.value("checkbox_build") == "true";
        VGlobal::setting.tool_bar_debug = toolbar.value("checkbox_debug") == "true";
        VGlobal::setting.tool_bar_std = toolbar.value("checkbox_std") == "true";
        VGlobal::setting.tool_bar_textedit =  toolbar.value("checkbox_textedit") == "true";

        // 快捷键
        QJsonArray array = parent.value("快捷键").toArray();
        foreach(QJsonValue value, array)
        {
            QJsonObject object = value.toObject();
            QJsonArray item_array = object.value("项目").toArray();
            foreach(QJsonValue value, item_array)
            {
                QJsonObject item_obj = value.toObject();
                QString name = item_obj.value("name").toString();
                QString short_cut = item_obj.value("short").toString();
                VGlobal::shortcut.insert(name, short_cut);
            }
        }
    }


    void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)

    {

        static QMutex mutex;

        mutex.lock();



        QString text;

        switch(type)
        {

        case QtDebugMsg:

            text = QString("Debug:");

            break;



        case QtWarningMsg:

            text = QString("Warning:");

            break;



        case QtCriticalMsg:

            text = QString("Critical:");

            break;

        case QtFatalMsg:

            text = QString("Fatal:");

        }

        QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);

        QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");

        QString current_date = QString("(%1)").arg(current_date_time);

        QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);



        QFile file(VGlobal::log_path);

        file.open(QIODevice::WriteOnly | QIODevice::Append);

        QTextStream text_stream(&file);

        text_stream << message << "\r\n";

        file.flush();

        file.close();

        mutex.unlock();

    }

    QString get_current_qss()
    {
        return read_file_text("D:/KoCode/build-KoCode-Desktop_Qt_5_6_2_MinGW_32bit-Debug/debug/skins/深色/index.qss");
    }

    void init_keyword_map()
    {
        VGlobal::keyword_cn_en.insert("引入", "include");
        VGlobal::keyword_cn_en.insert("宏定义", "define");
        VGlobal::keyword_cn_en.insert("短整型", "short");
        VGlobal::keyword_cn_en.insert("整数型", "int");
        VGlobal::keyword_cn_en.insert("长整型", "long");
        VGlobal::keyword_cn_en.insert("浮点型", "float");
        VGlobal::keyword_cn_en.insert("双精度", "double");
        VGlobal::keyword_cn_en.insert("字符型", "char");
        VGlobal::keyword_cn_en.insert("结构", "struct");
        VGlobal::keyword_cn_en.insert("联合", "union");
        VGlobal::keyword_cn_en.insert("枚举", "enum");
        VGlobal::keyword_cn_en.insert("类型定义", "typedef");
        VGlobal::keyword_cn_en.insert("只读", "const");
        VGlobal::keyword_cn_en.insert("无符号", "unsigned");
        VGlobal::keyword_cn_en.insert("有符号", "有符号");
        VGlobal::keyword_cn_en.insert("全局声明", "extern");
        VGlobal::keyword_cn_en.insert("注册", "register");
        VGlobal::keyword_cn_en.insert("静态", "static");
        VGlobal::keyword_cn_en.insert("易变的", "volatile");
        VGlobal::keyword_cn_en.insert("空类型", "void");
        VGlobal::keyword_cn_en.insert("如果", "if");
        VGlobal::keyword_cn_en.insert("否则", "else");
        VGlobal::keyword_cn_en.insert("选择", "switch");
        VGlobal::keyword_cn_en.insert("高级循环", "for");
        VGlobal::keyword_cn_en.insert("到", "do");
        VGlobal::keyword_cn_en.insert("循环", "while");
        VGlobal::keyword_cn_en.insert("跳到", "goto");
        VGlobal::keyword_cn_en.insert("跳过", "continue");
        VGlobal::keyword_cn_en.insert("跳出", "break");
        VGlobal::keyword_cn_en.insert("默认", "default");
        VGlobal::keyword_cn_en.insert("返回", "return");
        VGlobal::keyword_cn_en.insert("分支", "case");
        VGlobal::keyword_cn_en.insert("取大小", "sizeof");
        VGlobal::keyword_cn_en.insert("位于", "__at");
        VGlobal::keyword_cn_en.insert("特殊寄存器", "__sfr");
        VGlobal::keyword_cn_en.insert("特殊位", "__sbit");
        VGlobal::keyword_cn_en.insert("中断", "__interrupt");
        VGlobal::keyword_cn_en.insert("位型", "__bit");
        VGlobal::keyword_cn_en.insert("直接寻址", "__data");
        VGlobal::keyword_cn_en.insert("间接寻址8", "__pdata");
        VGlobal::keyword_cn_en.insert("间接寻址16", "__xdata");
        VGlobal::keyword_cn_en.insert("间接寻址256", "__idata");

        // 反向存储即可
        foreach(QString key, VGlobal::keyword_cn_en.keys())
        {
            VGlobal::keyword_en_cn.insert(VGlobal::keyword_cn_en.value(key), key);
        }
    }

    QString ctags(QString text)
    {
        VTranslate translate;
        translate.cn_en_map_clear();
        translate.cn_en_map_append_keyword();

        translate.set_comment_skip(true);
        translate.set_qutation_skip(true);

        QString en_text = translate.get_en_text(text);

        QString path = VGlobal::temp_dir + "/1.c";
        save_file(path, en_text);



        // 执行ctags
        QProcess p;
        p.start("\"" + VGlobal::ctags_path + "\"", QStringList()
            << "-R" << "--c++-kinds=+lpxzLNU" << "--fields=+aiKSzns" << "-f" << VGlobal::temp_dir+"/tags" << path);

//        qDebug() << "等待执行 ctags";
        if (p.waitForStarted() == false)
        {
            qDebug() << "ctags 启动失败";
        }
        p.waitForFinished();
//        qDebug() << "ctags 执行完毕!";

        // 读取 tags 文件
        QString file_text = read_file_text(VGlobal::temp_dir + "/tags");

        translate.set_comment_skip(false);
        translate.set_qutation_skip(false);

        translate.en_cn_map_clear();
//        translate.set_remap();

        QString result = translate.get_cn_text(file_text);

//        save_file("d:/1.txt", result);
        return result;
    }

    uint file_last_modify_time(QString path)
    {
        return QFileInfo(path).lastModified().toTime_t();
    }

    QString indent(QStringList parameter, QString text)
    {
        qDebug() << parameter;

        VTranslate translate;
        translate.cn_en_map_clear();
        translate.cn_en_map_append_keyword();

        translate.set_comment_skip(true);
        translate.set_qutation_skip(true);

        QString en_text = translate.get_en_text(text);

        QString path = VGlobal::temp_dir + "/temp.c";

        // 添加对asm的支持
        QRegularExpression reg("__asm(.+?)__endasm;");
        reg.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
        QRegularExpressionMatch match;
        match = reg.match(en_text);
        while(match.hasMatch())
        {
            QString cap_text = match.captured(1);
            cap_text = "{" + cap_text.replace("\r\n", ";\r\n") + "}";
            en_text  = en_text.replace(match.capturedStart(1), match.captured(1).length(), cap_text);
            match = reg.match(en_text, match.capturedStart() + 1);
        }


        save_file(path, en_text);



        // 执行indent
        QProcess p;
//        p.start("\"" + VGlobal::intent_path + "\"", QStringList()
//            << "-kr" << "-i4" << "-bl" << "-nce" << "-ts4" << "-ut" << "-bli0"
//                << "-nprs" << "-nsaf" << "-nsai" << "-nsaw" << VGlobal::temp_dir + "/temp.c");

        p.start("\"" + VGlobal::intent_path + "\"",
                parameter << VGlobal::temp_dir + "/temp.c");

        qDebug() << "等待执行 indent";
        if (p.waitForStarted() == false)
        {
            qDebug() << "indent 启动失败";
        }
        p.waitForFinished();
        qDebug() << "indent 执行完毕!";

        // 读取 tags 文件
        QString file_text = read_file_text(path);


        // 添加对asm的支持
        reg.setPattern("__asm(\\s*{)(.+?)(}\\s*)__endasm;");
        reg.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
        match = reg.match(file_text);
        while(match.hasMatch())
        {
            QString cap_text = match.captured(2);
            cap_text = cap_text.replace(";\r\n", "\r\n");
            cap_text = cap_text.replace("{", "");
            cap_text = cap_text.replace("}", "");
            file_text  = file_text.replace(match.capturedStart(1), match.captured(1).length()
                                           + match.captured(2).length() + match.captured(3).length(), cap_text);
            match = reg.match(file_text, match.capturedStart() + 1);
        }


        translate.en_cn_map_clear();
        translate.set_remap();
        QString result = translate.get_cn_text(file_text);

        // save_file(path, result);
        return result;
    }



    bool file_translate(QString source_path, QString save_dir, QString text, VTranslate &translate)
    {
        QString save_text;
        QString save_sufix;
        QString save_basenme;
        QString save_path;

        // 判断后缀
        save_sufix = QFileInfo(source_path).suffix();
        save_basenme = translate.get_en_word(QFileInfo(source_path).baseName());
        save_path = save_dir + "/" + save_basenme + "." + save_sufix;


        // 头文件预处理
        QRegExp reg("#(include|引入)(\\s+).([\u4e00-\u9fa5_.a-zA-Z0-9]+).");
        int reg_pos = reg.indexIn(text, 0);
        while (reg_pos > -1)
        {
            QString file_name = reg.cap(3);
            QString base_name = QFileInfo(file_name).baseName();
            QString suffix = QFileInfo(file_name).suffix();

            // 处理文件名和后缀
            base_name = translate.get_en_word(base_name);

            // join
            file_name = base_name + "." + suffix;

            int rpos = reg.pos(3);
            text = text.replace(rpos, reg.cap(3).length(), file_name);

            reg_pos = reg.indexIn(text, reg_pos + reg.cap(0).length());
        }

        // 文本translate
        translate.set_comment_skip(true);
        translate.set_qutation_skip(true);

        save_text = translate.get_en_text(text);
        translate._cn_en_map.insert(source_path, save_path);
        save_file(save_path, save_text);

        return true;
    }

    bool pack(QString source, QString save_path)
    {
        // %1 save path
        // %2 source path
        // a -tzip "%1" "%2" -r -mx=9 -m0=LZMA2 -ms=10m -mf=on -mhc=on -mmt=on

        // 执行7za.exe
        QProcess p;
        p.start("\"" + VGlobal::compress_path + "\"", QStringList()
            << "a" << "-tzip" << save_path << source << "-r");

        qDebug() << "等待执行 pack";
        if (p.waitForStarted() == false)
        {
            qDebug() << "pack 启动失败";
        }
        p.waitForFinished();
        qDebug() << "pack 执行完毕!";
    }

    QStringList get_file_path_list(QString path)
    {
        QStringList result;

        QDir dir(path);
        foreach(QFileInfo mfi ,dir.entryInfoList())
        {
            if(mfi.isFile())
            {
                result.append(mfi.absoluteFilePath());
            }
        }
        return result;
    }

    QStringList get_folder_list(QString path)
    {
        QStringList result;

        QDir dir(path);
        foreach(QFileInfo mfi ,dir.entryInfoList())
        {
            if(mfi.isFile() == false)
            {
                if(mfi.fileName()=="." || mfi.fileName() == "..")continue;

                result.append(mfi.absoluteFilePath());
            }
        }
        return result;
    }

    void recursion_project_all_file_path(QJsonArray arr, QStringList &result);
    void recursion_project_all_file_path(QJsonArray arr, QStringList &result)
    {
        {
            foreach(QJsonValue value, arr)
            {
                QJsonObject child = value.toObject();

                QJsonArray child_folder = child.value("folder").toArray();
                if(child_folder.count() > 0)
                {
                    recursion_project_all_file_path(child_folder, result);
                }

                QJsonArray child_file = child.value("file").toArray();
                foreach(QJsonValue file, child_file)
                {
                    QString relative = file.toString();
                    result.append(relative);
                }
            }

        }
    }

    QStringList get_project_all_file_path(QString esln_path)
    {


        QStringList file_name_list = get_project_all_file_name(esln_path);
        QString current_folder = QFileInfo(esln_path).path();
        QDir dir;

        // 转化为绝对路径
        QStringList result;
        foreach(QString relative_path, file_name_list)
        {
            if(dir.isRelativePath(relative_path))
            {
                dir.setCurrent(current_folder);
                dir.cd(relative_path);
                QString file_name = QFileInfo(relative_path).fileName();
                result.append(dir.absolutePath() + "/" + file_name);
            }
            else
            {
                result.append(relative_path);
            }
        }
        return result;

    }

    QStringList get_project_all_file_name(QString esln_path)
    {
        QStringList file_name_list;

        QString project_json_text = VFunctions::read_file_text(esln_path);
        QString base_name = QFileInfo(esln_path).baseName();
        QString source_path = QFileInfo(esln_path).path() + "/" + base_name;

        QJsonParseError json_error;
        QJsonDocument json_document = QJsonDocument::fromJson(project_json_text.toUtf8(), &json_error);
        if(json_error.error != QJsonParseError::NoError)
        {
            // QMessageBox::critical(this, "错误", QString("%1 解析失败").arg(esln_path));
            return QStringList();
        }

        QJsonObject root = json_document.object().value("root").toObject();

        // 载入文件夹
        QJsonArray folder_arr = root.value("folder").toArray();
        recursion_project_all_file_path(folder_arr, file_name_list);

        // 载入文件
        QJsonArray file_arr = root.value("file").toArray();
        foreach(QJsonValue value, file_arr)
        {
            file_name_list.append(value.toString());
        }
        return file_name_list;
    }

    QStringList get_skins_names()
    {
        QStringList list;
        QDir dir(VGlobal::skins_dir);
        foreach(QFileInfo mfi ,dir.entryInfoList())
        {
            if(mfi.isFile() == false)
            {
                if(mfi.fileName()=="." || mfi.fileName() == "..")continue;
                list.append(mfi.fileName());
            }
        }
        return list;
    }

    QJsonDocument get_file_jsonDocument(QString path)
    {
        QJsonParseError json_error;
        QString text = read_file_text(path);
        QJsonDocument json_document = QJsonDocument::fromJson(text.toUtf8(), &json_error);
        if(json_error.error != QJsonParseError::NoError)
        {
            // QMessageBox::critical(this, "错误", QString("%1 解析失败").arg(esln_path));
            qDebug() << QString("%1 解析失败").arg(path);
            return QJsonDocument();
        }

        return json_document;
    }

    bool file_append_text(QString path, QString text)
    {
        QFile file(path);
        if (!file.open(QIODevice::WriteOnly|QIODevice::Append))
        {
            // error
        }

        QTextStream out(&file);
        out.setCodec("utf-8");
        out << text;
        file.close();
    }

    QString get_today()
    {
        QDateTime local(QDateTime::currentDateTime());
        QString localTime = local.toString("yyyy-MM-dd");
        return localTime;
    }

    QString string_reverse(QString text)
    {
        QString result;
        result.clear();

        for(int i=text.length()-1; i>=0; i--)
        {
            result += text.at(i);
        }


        return result;

//        int length = text.length();
//        for(int i=0; i< text.length(); i++)
//        {
//            result.
//            result.at(i) = text.at(length - i -1);
//        }
        return text;
    }

    QString string_regexp(QString text, QString regexp, int nth)
    {
        QRegularExpression reg(regexp);
//        reg_insert.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
        QRegularExpressionMatch match = reg.match(text);
        if(match.hasMatch())
        {
            return match.captured(nth);
        }
        return "";
    }

    int string_count(QString text, QChar c)
    {
        int i=0;
        foreach(QChar child, text)
        {
            if(child == c)
            {
                i++;
            }
        }
        return i;
    }

    int RGB2BGR(int color)
    {
        int n1 = color % 256;
        int n2 = color / 65536;
        int mid = color - n1 - n2*65536;
        return n1*65536 + mid + n2;
    }

}
